using System;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.MultiTenancy;
using Xms.Abp.BackgroundJob;

namespace Xms.Abp.Messaging.Emailing;

/// <summary>
/// This class can be used as base to implement <see cref="IEmailSender"/>.
/// </summary>
public abstract class EmailSenderBase : IEmailSender
{
    protected IBackgroundJobManager BackgroundJobManager { get; }
    protected ICurrentTenant CurrentTenant { get; }

    /// <summary>
    /// Constructor.
    /// </summary>
    protected EmailSenderBase(
        IBackgroundJobManager backgroundJobManager,
        ICurrentTenant currentTenant)
    {
        BackgroundJobManager = backgroundJobManager;
        CurrentTenant = currentTenant;
    }

    public virtual async Task SendAsync(EmailMessage emailMessage, CancellationToken stoppingToken = default)
    {
        await SendEmailAsync(emailMessage, stoppingToken);
    }

    public virtual async Task QueueAsync(EmailMessage emailMessage, BackgroundJobPriority priority = BackgroundJobPriority.Normal, CancellationToken stoppingToken = default)
    {
        if (!BackgroundJobManager.IsAvailable())
        {
            await SendAsync(emailMessage);
            return;
        }
        await BackgroundJobManager.EnqueueAsync(emailMessage, CurrentTenant.Id, priority, timeout: 10, maxTryCount: 5);
    }

    /// <summary>
    /// Should implement this method to send email in derived classes.
    /// </summary>
    /// <param name="mail">Mail to be sent</param>
    protected abstract Task SendEmailAsync(EmailMessage emailMessage, CancellationToken stoppingToken = default);
}
